from django.db import transaction
from rest_framework import serializers

from goods.models import SKU, GoodsCategory, SPUSpecification, SKUSpecification
from celery_tasks.static_html.tasks import get_detail_html

class SKUSpecificationSerializer(serializers.ModelSerializer):
    spec_id=serializers.IntegerField()
    option_id=serializers.IntegerField()
    class Meta:

        model=SKUSpecification
        fields=('spec_id','option_id')


# sku序列化器
class SKUSerializer(serializers.ModelSerializer):
    # 关联对象嵌套序列化返回
    spu=serializers.StringRelatedField(read_only=True)
    spu_id=serializers.IntegerField()

    category=serializers.StringRelatedField(read_only=True)
    category_id=serializers.IntegerField()

    # sku具体规格选项
    specs=SKUSpecificationSerializer(many=True)


    class Meta:
        model=SKU
        fields='__all__'

    # 重写父类create方法完成sku规格详情保存
    # @transaction.atomic()
    def create(self, validated_data):
        # 开启事务
        with transaction.atomic():
            # 设置保存点
            save_point=transaction.savepoint()
            try:
                # 2.数据库保存
                # 3. 保存sku表数据
                # 获取specs
                specs=validated_data['specs']
                # 删除specs
                del validated_data['specs']
                sku=SKU.objects.create(**validated_data)
                # 4.保存sku具体规格表信息
                # request=self.context['request']
                # specs=request.data['specs']
                for spec in specs:
                    SKUSpecification.objects.create(sku=sku,spec_id=spec['spec_id'],option_id=spec['option_id'])

            except:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError("保存失败")
            transaction.savepoint_commit(save_point)

            # 静态化生成新的详情页面
            get_detail_html.delay(sku.id)
            return sku

    def update(self, instance, validated_data):
        # 开启事务
        with transaction.atomic():
            # 设置保存点
            save_point=transaction.savepoint()
            try:
                # 2.数据库保存
                # 3. 修改sku表数据
                # 获取specs
                specs=validated_data['specs']
                # 删除specs
                del validated_data['specs']
                SKU.objects.filter(id=instance.id).update(**validated_data)
                # 4.修改sku具体规格表信息
                # request=self.context['request']
                # specs=request.data['specs']
                for spec in specs:
                    SKUSpecification.objects.filter(sku=instance,spec_id=spec['spec_id']).update(option_id=spec['option_id'])

            except:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError("保存失败")
            transaction.savepoint_commit(save_point)
            sku=SKU.objects.get(id=instance.id)

            # 静态化生成新的详情页面
            get_detail_html.delay(sku.id)

            return sku

# 商品分类序列化器
class GoodsCategorySerializer(serializers.ModelSerializer):

    class Meta:
        model=GoodsCategory
        fields=('id','name')

# 规格选项序列化器
class SPUSpecificationSerializer(serializers.ModelSerializer):
    # 商品规格选项序列化器
    class Meta:
        model = SPUSpecification
        fields = ('id', 'value')

# 规格序列化器
class SPUSpecificationSerializer(serializers.ModelSerializer):
    """商品规格序列化器"""
    # 关联对象嵌套序列化返回,
    # spu是父表，子表嵌套父表返回
    spu=serializers.StringRelatedField(read_only=True)
    spu_id=serializers.IntegerField()
    # 关联对象嵌套序列化返回
    # SPUSpecification是父表，父表嵌套子表返回
    options=SPUSpecificationSerializer(many=True)


    class Meta:
        model=SPUSpecification
        fields='__all__'